package com.talkweb.securitycamera.module;

import com.talkweb.securitycamera.cameraInterface.ICameraModule;
import com.talkweb.securitycamera.cameraInterface.ICameraConfigChangeCallback;
import com.talkweb.securitycamera.common.constans.FileType;
import com.talkweb.securitycamera.common.interfaces.dataprocess.IFileGet;
import ohos.agp.graphics.Surface;
import ohos.app.Context;
import ohos.app.dispatcher.task.TaskPriority;
import ohos.media.camera.device.Camera;
import ohos.media.camera.device.FrameConfig;
import ohos.media.image.Image;
import ohos.media.image.ImageReceiver;
import ohos.media.image.common.ImageFormat;
import ohos.media.image.common.Size;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import static ohos.media.camera.device.Camera.FrameConfigType.FRAME_CONFIG_PICTURE;

/**
 * @version 1.0.1
 * @description:相机拍照模块
 * @program: security-camera
 * @Author xiaozhijun
 * @Date 2021/3/02 14:35
 */
public class CameraPictureModule implements ICameraModule {

    private Context mContext;
    //图片接收
    ImageReceiver imageReceiver;

    //缓存文件获取接口
    private IFileGet imageFileGet;

    public CameraPictureModule(Context context) {
        this.mContext = context;
    }


    @Override
    public Surface getSurface() {
        return imageReceiver != null ? imageReceiver.getRecevingSurface() : null;
    }

    @Override
    public void start(Camera camera, Surface surface) {
        changeFrameConfig(camera);
    }

    @Override
    public void stop(Camera camera) {

    }

    @Override
    public void changeFrameConfig(Camera camera) {
        // 获取拍照配置模板
        FrameConfig.Builder framePictureConfigBuilder = camera.getFrameConfigBuilder(FRAME_CONFIG_PICTURE);
        // 配置拍照 Surface
        framePictureConfigBuilder.addSurface(imageReceiver.getRecevingSurface());
        try {
            // 启动单帧捕获(拍照)
            int id = camera.triggerSingleCapture(framePictureConfigBuilder.build());
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        }
    }

    @Override
    public File getFile() {
        if (imageFileGet != null) {
            return imageFileGet.createSourceFile(FileType.FILE_TYPE_IMAGE);
        }
        return null;
    }

    @Override
    public void init(Size properSize, IFileGet fileGet) {
        takePictureInit(properSize);
    }

    @Override
    public ICameraConfigChangeCallback getConfigChangeCallback() {
        return null;
    }

    // 单帧捕获生成图像回调Listener
    private final ImageReceiver.IImageArrivalListener imageArrivalListener = new ImageReceiver.IImageArrivalListener() {
        @Override
        public void onImageArrival(ImageReceiver imageReceiver) {
            File cacheFile = getFile();
            if (cacheFile != null) {
                ImageSaver imageSaver = new ImageSaver(imageReceiver.readNextImage(), cacheFile); // 创建一个读写线程任务用于保存图片
                mContext.getGlobalTaskDispatcher(TaskPriority.DEFAULT).asyncDispatch(imageSaver); // 执行读写线程任务生成图片
            }

        }
    };

    // 保存图片, 图片数据读写，及图像生成见run方法
    static class ImageSaver implements Runnable {
        private final Image myImage;
        private final File myFile;

        ImageSaver(Image image, File file) {
            myImage = image;
            myFile = file;
        }

        @Override
        public void run() {
            Image.Component component = myImage.getComponent(ImageFormat.ComponentType.JPEG);
            byte[] bytes = new byte[component.remaining()];
            component.read(bytes);
            FileOutputStream output = null;
            try {
                output = new FileOutputStream(myFile);
                output.write(bytes); // 写图像数据
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (output != null) {
                    try {
                        output.close(); // 关闭流
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                myImage.release();
            }
        }
    }


    /**
     * 截屏初始化
     *
     * @param properSize 大小Size
     */
    private void takePictureInit(Size properSize) {
        // 创建 ImageReceiver 对象，注意 create 函数中宽度要大于高度； 5 为最大支持的图像数，请根据实际设置。
        imageReceiver = ImageReceiver.create(Math.max(properSize.width, properSize.height),
                Math.min(properSize.width, properSize.height), ImageFormat.JPEG, 5);
        imageReceiver.setImageArrivalListener(imageArrivalListener);

    }

    public void setImageFileGet(IFileGet imageFileGet) {
        this.imageFileGet = imageFileGet;
    }
}
